#include "stdafx.h"
#include "BufferLayout.h"

namespace Reign
{namespace Video
{namespace D3D10
{
	#pragma region Constructors
	BufferLayout^ BufferLayout::New(DisposableI^ parent, ShaderI^ shader, BufferLayoutDescI^ bufferLayoutDesc)
	{
		BufferLayout^ layout = parent->FindChild<BufferLayout^>(gcnew string(L"New"),
			gcnew ConstructorParam(DisposableI::typeid, parent),
			gcnew ConstructorParam(ShaderI::typeid, shader),
			gcnew ConstructorParam(BufferLayoutDescI::typeid, bufferLayoutDesc));
		if (layout)
		{
			++layout->referenceCount;
			return layout;
		}
		return gcnew BufferLayout(parent, shader, bufferLayoutDesc);
	}

	BufferLayout::BufferLayout(DisposableI^ parent, ShaderI^ shader, BufferLayoutDescI^ bufferLayoutDesc)
	: Disposable(parent)
	{
		null();
		try
		{
			video = parent->FindParentOrSelfWithException<Video^>();
			BufferLayoutDesc^ bufferLayoutDescTEMP = (BufferLayoutDesc^)bufferLayoutDesc;
			Shader^ shaderTEMP = (Shader^)shader;

			ID3D10InputLayout* layoutTEMP;
			if (FAILED(video->Device->CreateInputLayout(bufferLayoutDescTEMP->Desc, bufferLayoutDescTEMP->ElementCount, shaderTEMP->Vertex->code->GetBufferPointer(), shaderTEMP->Vertex->code->GetBufferSize(), &layoutTEMP)))
			{
				layout = 0;
				Debug::ThrowError(L"BufferLayout", L"Failed to create InputLayout");
			}
			layout = layoutTEMP;
		}
		catch (Exception^ ex)
		{
			delete this;
			throw ex;
		}
	}

	BufferLayout::~BufferLayout()
	{
		disposeChilderen();
		if (layout) layout->Release();
		null();
	}

	void BufferLayout::null()
	{
		layout = 0;
		video = nullptr;
	}
	#pragma endregion
	
	#pragma region Methods
	void BufferLayout::Enable() {video->Device->IASetInputLayout(layout);}
	#pragma endregion
}
}
}